﻿using System;
using CommonLib;
namespace CommonDAL
{
    public class OptimisticConcurrencyException : ApplicationException
    {
        public IDataEntity DataEntity { get; protected set; }

        public OptimisticConcurrencyException(IDataEntity dataEntity, string message) : base(message)
        {
            DataEntity = dataEntity;
        }
    }
    public class DirtyEventArgs : EventArgs
    {
        public IDataEntity DirtyEntity { get; protected set; }
        public DirtyEventArgs(IDataEntity dirtyEntity)
        {
            DirtyEntity = dirtyEntity;
        }
    }
    public class ConstraintIntegrityEventArgs : EventArgs
    {
        public IDataEntity ReferencingEntity { get; protected set; }
        public IDataEntity ReferencedEntity { get; protected set; }
        public ConstraintIntegrityEventArgs(IDataEntity referencingEntity, IDataEntity referencedEntity)
        {
            ReferencingEntity = referencingEntity;
            ReferencedEntity = referencedEntity;
        }
    }

    public enum DataEntityState
    {
        None,
        Clean,
        New,
        Dirty,
        Deleted,
    }

    public interface IDataEntity
    {
        event EventHandler<DirtyEventArgs> Dirty;
        event EventHandler<ConstraintIntegrityEventArgs> ConstraintIntegrity;

        DataEntityState EntityState { get; }
        bool IsNew { get; }
        bool IsDirty { get; }

        int Update();
        void Create();
        int Delete();
    }

    public interface IDataEntity<TIdentity> : IDataEntity
        where TIdentity : struct
    {
        TIdentity? Identity { get; set; }
    }

    public interface IDataEntity<TIdentity, TUniqueKey, TBusinessEntity> :
        IDataEntity<TIdentity>
        where TIdentity : struct
        where TUniqueKey : struct
        where TBusinessEntity : IBusinessEntity<TUniqueKey>
    {
        // TUniqueKey UniqueKey { get; }
        TBusinessEntity BusinessEntity { get; }
        long Version { get; set; }
        TIdentity Insert();
    }

    public interface IDataEntityL<TUniqueKey, TBusinessEntity> : IDataEntity<long, TUniqueKey, TBusinessEntity>
        where TUniqueKey : struct
        where TBusinessEntity : IBusinessEntity<TUniqueKey>
    {
    }
}
